package uk.org.mygrid.eobesity.csvserver;

import org.apache.log4j.Logger;
import org.restlet.Application;
import org.restlet.Restlet;
import org.restlet.routing.Router;
import org.slf4j.bridge.SLF4JBridgeHandler;

import uk.org.mygrid.eobesity.csvserver.routes.ClientAccessPolicy;
import uk.org.mygrid.eobesity.csvserver.routes.DatasetUpload;
import uk.org.mygrid.eobesity.csvserver.routes.DownloadFile;
import uk.org.mygrid.eobesity.csvserver.routes.FetchZipFile;
import uk.org.mygrid.eobesity.csvserver.routes.HelloWorldResource;

/**
 * Sets up the routes ie URLs to class association for the CSV Dataset server
 * 
 * @author Ian Dunlop
 * 
 */
public class CSVRESTService extends Application {

//    private static final String LOGGER_NAME = "org.mortbay.log";
    private static final String DOWNLOAD_CSV_DATASETS = "/eos/download";
    private static final String FETCH_ZIP_FILE = "/eos/download/{jobid}";
    private static final String CLIENT_ACCESS_POLICY = "/crossdomain.xml";
    private static final String DATASET_UPLOAD = "/eos/dataset";
//    private Configuration config;
    private static Logger logger = Logger.getLogger(CSVRESTService.class);
//
//	private Configuration config;
//
//	public Configuration getConfig() {
//		return config;
//	}
//
//	public void setConfig(Configuration config) {
//		this.config = config;
//	}

    public CSVRESTService() {
//		parentContext.createChildContext();
		initialiseService();
    }

    /**
     * Set up logging and reload the completed job map
     */
    public void initialiseService() {
        SLF4JBridgeHandler.install();
//        checkJobs(BaseResource.getCompletedJobList());
//		try {
//			config = new PropertiesConfiguration("csv.properties");
//		} catch (Exception e) {
//			logger.error("Problem with service properties",e);
//
//		}
//		String serializeDirectory = config.getString("SerializeMap.0");
//		File file = new File(serializeDirectory + "jobMap");
//		try {
//			FileInputStream stream = new FileInputStream(file);
//			ObjectInputStream objectStream = new ObjectInputStream(stream);
//			completedJobList =  (ConcurrentMap<String, Boolean>) objectStream
//					.readObject();
//			objectStream.close();
//			checkJobs(completedJobList);
////			DownloadFile.setCompletedJobList(completedJobList);
//		} catch (FileNotFoundException e) {
////			getLogger().warning("Problem de-serializing job map, " + e);
//			logger.warn("Problem de-serializing job map, " + e);
//		} catch (IOException e) {
////			getLogger().warning("Problem de-serializing job map, " + e);
//			logger.warn("Problem de-serializing job map, " + e);
//		} catch (ClassNotFoundException e) {
////			getLogger().warning("Problem de-serializing job map, " + e);
//			logger.warn("Problem de-serializing job map, " + e);
//		}
    }

//    /**
//     * When loading the job map they should all be complete, ie, true. If not
//     * then we have to re-run any that failed to complete
//     */
//    private void checkJobs(Map<String, Boolean> completedJobList) {
//        Set<Entry<String, Boolean>> entrySet = completedJobList.entrySet();
//        for (Entry<String, Boolean> entry : entrySet) {
//            if (entry.getValue() == false) {
//                try {
//                    Map<String, List<String>> loadDatasetMap = loadDatasetMap(entry.getKey());
//                    entry.getKey();
//                    createJobThread(entry.getKey(), loadDatasetMap).start();
//                } catch (Exception e) {
                    // job failed and can't load the variables map so have to
                    // mark it as failed so that the user
                    // can see next time they look at it
//					DownloadFile.getFailedJobs().add(entry.getKey());
//					getLogger()
//							.severe(
//									"Problem loading dataset for job "
//											+ entry.getKey()
//											+ ", cannot re-run csv for this file. User must re-create. "
//											+ e);
//                    logger.error("Problem loading dataset for job "
//                            + entry.getKey()
//                            + ", cannot re-run csv for this file. User must re-create. "
//                            + e);
//                }
//            }
//        }
//    }

//    /**
//     * Reload a dataset map for a job which failed to run to completion
//     *
//     * @param uuid
//     * @return
//     * @throws IOException
//     * @throws ClassNotFoundException
//     */
//    @SuppressWarnings("unchecked")
//    private Map<String, List<String>> loadDatasetMap(String uuid)
//            throws IOException, ClassNotFoundException {
////		String serializeDirectory = Messages.getString("SerializeMap.0");
//        String serializeDirectory = config.getString("SerializeMap.0");
//        File file = new File(serializeDirectory + uuid + ".variableMap");
//        try {
//            FileInputStream stream = new FileInputStream(file);
//            ObjectInputStream objectStream = new ObjectInputStream(stream);
//            Map<String, List<String>> datasetToVariableMap = (Map<String, List<String>>) objectStream.readObject();
//            objectStream.close();
//            return datasetToVariableMap;
//        } catch (FileNotFoundException e) {
////			getLogger().warning("Problem de-serializing job map" + ": " + e);
//            logger.warn("Problem de-serializing job map" + ": " + e);
//            throw new FileNotFoundException("Problem de-serializing job map");
//        } catch (IOException e) {
////			getLogger().warning("Problem de-serializing job map" + ": " + e);
//            logger.warn("Problem de-serializing job map" + ": " + e);
//            throw new IOException("Problem de-serializing job map");
//        } catch (ClassNotFoundException e) {
////			getLogger().warning("Problem de-serializing job map" + ": " + e);
//            logger.warn("Problem de-serializing job map" + ": " + e);
//            throw new ClassNotFoundException("Problem de-serializing job map");
//        }
//    }

    /**
     * Creates all the Routes for the Restlet server. Associates urls with the
     * classes which handle them
     */
    @Override
    public synchronized Restlet createInboundRoot() {

        Router router = new Router(getContext());

        router.attach(CLIENT_ACCESS_POLICY, ClientAccessPolicy.class);

        router.attach(FETCH_ZIP_FILE, FetchZipFile.class);

        router.attach(DOWNLOAD_CSV_DATASETS, DownloadFile.class);
        
        router.attach(DATASET_UPLOAD, DatasetUpload.class);

        router.attach("/hello", HelloWorldResource.class);

        logger.info("routes attached");

        return router;
    }

//    /**
//     * Create a new job thread for a job which previously failed to run to
//     * completion
//     *
//     * @param jobID
//     * @param datasetToVariableMap
//     * @return
//     */
//    private Thread createJobThread(final String jobID,
//            final Map<String, List<String>> datasetToVariableMap) {
//        getLogger().info("Re-running CSV data for " + jobID);
//        Thread thread = new Thread(new Runnable() {
//
//            public void run() {
//                try {
//
//                    Set<Entry<String, List<String>>> entrySet = datasetToVariableMap.entrySet();
//                    List<File> fileList = new ArrayList<File>();
//                    CSVUtils csvTester = new CSVUtils();
//                    for (Entry<String, List<String>> entry : entrySet) {
//                        Map<String, List<String>> readFieldNames;
//                        try {
//                            String key = entry.getKey();
//                            List<String> value = entry.getValue();
//                            getLogger().info(
//                                    "Loading data- " + key + ": " + value);
//                            logger.info("Loading data- " + key + ": " + value);
//                            readFieldNames = csvTester.readFieldNames(key,
//                                    value);
//
//                            getLogger().info(
//                                    "Creating file- " + key + ": " + value);
//                            logger.info("Creating file- " + key + ": " + value);
//                            File csvWriter = csvTester.CSVWriter(
//                                    entry.getKey(), readFieldNames, jobID);
//                            fileList.add(csvWriter);
//                        } catch (FileNotFoundException e) {
//                            getLogger().severe(
//                                    "Problem creating csv for " + jobID + ": "
//                                    + e);
//                            logger.error("Problem creating csv for " + jobID + ": "
//                                    + e);
//                            throw e;
//                        }
//                    }
//                    getLogger().info("Adding files to zip- " + fileList);
//                    logger.info("Adding files to zip- " + fileList);
//                    csvTester.zipWriter(fileList, jobID);
//
//                    BaseResource.getCompletedJobList().put(jobID, true);
//                    getLogger().info(
//                            BaseResource.getCompletedJobList().toString());
//                } catch (FileNotFoundException e) {
//                    getLogger().severe(
//                            "Problem creating csv for " + jobID + ": " + e);
//                    logger.info("Problem creating csv for " + jobID + ": " + e);
//
//                }
//            }
//        });
//        return thread;
//    }

//    /**
//     * Start the restlet server logging
//     */
//    private void initializeRestletLogging() {
//
//        Handler[] handlers = java.util.logging.Logger.getLogger("") //$NON-NLS-1$
//                .getHandlers();
//        for (Handler handler : handlers) {
//            handler.setFormatter(new ReallySimpleFormatter());
//        }
//        java.util.logging.Logger.getLogger(LOGGER_NAME).setLevel(Level.INFO);
//
//    }
}
